﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dapper.Liquid;
using System.Web;
using System.Web.Caching;
using System.IO;
using Dapper.Liquid.FileSystems;

namespace Dapper.Core
{
    public static class TemplateHelper
    {

        #region Template路径

        static TemplateHelper()
        {
            //可用文件配置，例子中用了字典
            _map = new Dictionary<string, string>(50);
            _map.Add("master", "~/template/master.htm");
            _map.Add("index_content_main", "~/template/index_content_main.htm");
            _map.Add("list_content_main", "~/template/list_content_main.htm");
            _map.Add("list_content_script", "~/template/list_content_script.htm");
            _map.Add("detail", "~/template/uc/detail.htm");
        }

        #endregion

        private static Dictionary<string, string> _map;

        public static bool ContainsKey(string key)
        {
            return _map.ContainsKey(key);
        }
        public static string GetTemplateURL(string key)
        {
            try
            {
                return _map[key];
            }
            catch (KeyNotFoundException e)
            {
                KeyNotFoundException ne = new KeyNotFoundException(e.Message + "key:" + key);
                throw ne;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /*这个方法限制了文件模板路径必要配置，如果需要可以添加直接以文件路径为参数的方法，
         *不过感觉这里配置起来是个好的习惯 */
        public static Template GetFileTemplate(string templateKey, Encoding encoding)
        {
            Template template = HttpContext.Current.Cache[templateKey] as Template;
            if (template == null)
            {
                string path = HttpContext.Current.Server.MapPath(GetTemplateURL(templateKey));
                template = Template.Parse(File.ReadAllText(path, encoding));
                CacheDependency dependency = new CacheDependency(path);
                HttpContext.Current.Cache.Add(templateKey, template, dependency, Cache.NoAbsoluteExpiration,
                    Cache.NoSlidingExpiration, CacheItemPriority.Default, null);//把模板缓存起来
            }
            return template;
        }

        public static Template GetFileTemplate(string templateKey)
        {
            return GetFileTemplate(templateKey, Encoding.UTF8);
        }
    }


    public class IncludeFileSystem : IFileSystem
    {
        private Encoding _encoding = Encoding.Default;

        public IncludeFileSystem() { }

        public IncludeFileSystem(Encoding encoding)
        {
            _encoding = encoding;
        }

        public string ReadTemplateFile(Context context, string templateName)
        {

            bool isOptional = false; //是否可选
            string templateKey = templateName;
            if (templateName.EndsWith("_optional"))
            {
                isOptional = true;
                templateKey = templateKey.Replace("_optional", "");
            }

            if (templateKey.StartsWith("content_"))
            {
                object ns = context.Environments[0]["ns"];
                if (ns == null)
                {
                    ns = Path.GetFileNameWithoutExtension(HttpContext.Current.Request.RawUrl);
                }
                templateKey = ns + "_" + templateKey;
            }
            object result = HttpContext.Current.Cache[templateKey];
            if (result == null)
            {
                if (isOptional && !TemplateHelper.ContainsKey(templateKey))
                {
                    return string.Empty;
                }
                string path = HttpContext.Current.Server.MapPath(TemplateHelper.GetTemplateURL(templateKey));
                result = File.ReadAllText(path, Encoding.UTF8);
                CacheDependency dependency = new CacheDependency(path);
                HttpContext.Current.Cache.Add(templateKey, result, dependency, Cache.NoAbsoluteExpiration,
                    Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
            }
            return result.ToString();
        }
    }


    public class TemplateFilters
    {
        public static string Text(bool? input, string trueText, string falseText, string nullText)
        {
            if (input == null) return nullText;
            return input == true ? trueText : falseText;
        }
        public static string Text(bool input, string trueText, string falseText)
        {
            return input ? trueText : falseText;
        }
    }
}
